#ifndef _X_LOG_FORMAT_H
#define _X_LOG_FORMAT_H
#include "xLogLevel.h"
#include "xLogEvent.h"
#include <vector>
#include <memory>
#include <sys/syscall.h>
#include <stdarg.h>
#include <string.h>
namespace XLog
{
    
    /*
        time level threadID fileName funcName line content
    */
    class XLogFormat
    {
    public:
        // %t %l %d %f %m %n %c
        XLogFormat(std::string fmt) : format(fmt){
            this->splite();
        }
        ~XLogFormat();
    public:
        void setFormat(std::string fmt);

        std::string out(const XLogEvent* event);

        class XLogFormatItem 
        {
        public:
            typedef std::shared_ptr<XLogFormatItem> XLogFormatItemPtr;
            virtual ~XLogFormatItem(){}
            virtual std::string out(const XLogEvent* event)=0;
        };

        class XLogFormatTime : public XLogFormatItem
        {
        public:
            std::string out(const XLogEvent* event);
        };

        class XLogFormatLevel : public XLogFormatItem
        {
        public:
            std::string out(const XLogEvent* event);
            static std::string strLevel(XLogLevel::Level level)
            {
                switch(level)
                {
                    case XLogLevel::XLOG_LEVEL_DEBUG: return "DEBUG";
                    case XLogLevel::XLOG_LEVEL_INFO:  return "INFO";
                    case XLogLevel::XLOG_LEVEL_WARN:  return "WARN";
                    case XLogLevel::XLOG_LEVEL_ERROR: return "ERROR";
                    default:                          return "DEFAULT";
                }
            };
        };

        class XLogFormatThreadID : public XLogFormatItem
        {
        public:
            std::string out(const XLogEvent* event) override;
        };

        class XLogFormatFileName : public XLogFormatItem
        {
        public:
            std::string out(const XLogEvent* event) override;
        };

        class XLogFormatFuncName : public XLogFormatItem
        {
        public:
            std::string out(const XLogEvent* event) override;
        };

        class XLogFormatLine : public XLogFormatItem
        {
        public:
            std::string out(const XLogEvent* event) override;
        };

        class XLogFormatContent : public XLogFormatItem
        {
        public:
            std::string out(const XLogEvent* event) override;
        };

        class XLogFormatError : public XLogFormatItem
        {
        public:
            std::string out(const XLogEvent* event) override;
        };

        static XLogFormatItem* create(const char fmt);
    private:
        void splite();
    private:
        std::string format;
        typedef std::vector<XLogFormatItem*> XLogFormatItemContainer;
        XLogFormatItemContainer vecFormatItem;
    };
}

#endif